import { QNMPPlugin } from '@yolanda-qn/qn-mp-plugin';
import { HandheldHeightProtocol } from '@yolanda-qn/handheld-height-protocols';

// wxb0989a4bbce13d87为测试用appid, 记得切换为客户自己的
const APPID = 'wxb0989a4bbce13d87';

/**
 * 微信的本地日志功能，需要用户手动反馈才能拿到日志文件
 */
const logger = () => {
  const wxlogger =
    wx.getLogManager &&
    wx.getLogManager({
      level: 0,
    });
  const log = (...params) => {
    console.log(...params);
    wxlogger && wxlogger.log(...params);
  };
  return {
    log,
  };
};

const DEVICE_UNIT_MAP = {
  CM: 1,
  FT_IN: 2,
  IN: 4,
  FT: 8,
};

const BleOpStatusEnum = {
  // 初始状态，未init前
  NOOP: 'NOOP',
  // 蓝牙不可用
  BLE_DISABLED: 'BLE_DISABLED',
  // 蓝牙可用
  BLE_READY: 'BLE_READY',
  // 正在扫描
  SCANNING: 'SCANNING',
  // 停止扫描
  STOP_SCANNING: 'STOP_SCANNING',
  // 已发现设备
  DEVICE_FOUNDED: 'DEVICE_FOUNDED',
  // 正在连接
  CONNECTING: 'CONNECTING',
  // 已连接
  CONNECTED: 'CONNECTED',
  // 连接失败
  CONNECT_FAILED: 'CONNECT_FAILED',
  // 断开连接
  DISCONNECTED: 'DISCONNECTED',
  // 连接超时
  CONNECT_OVERTIME: 'CONNECT_OVERTIME',
  // 例如：正在测量
  OPERATING: 'OPERATING',
  // 例如：测量完成
  OPERATE_FINISHED: 'OPERATE_FINISHED',
  // 发生了错误
  ERROR_OCCURED: 'ERROR_OCCURED',
};

Page({
  data: {
    height: '',
    heightUnit: '',
    userIndex: '',
    deviceId: '',
    historyData: [],
    deviceInfo: {},
    bleOpStatus: BleOpStatusEnum.NOOP,
    bleOpStatusText: '初始化中...',
    connecting: false,
    DEVICE_UNIT_MAP,
  },
  onLoad: function(options) {
    if (options.form) {
      const form = JSON.parse(options.form);
      this.setData({
        ...form,
      });
    }
    if (options.type) {
      this.setData({
        type: options.type,
      });
    }

    /**
     * 实例化插件
     * @see [QNMPPlugin](../README.md#QNMPPlugin)
     */
    this.bleApi = new QNMPPlugin({
      appId: APPID, // 必须, 客户小程序的appid, 需要配置才能使用，
      logger: logger(), // 非必须，日志功能，最好有，方便排查问题，可以替换为客户自己的
      useUploadStoredData: true, // 是否需要上传存储记录，需要已配网
      protocols: [HandheldHeightProtocol], // 需要链接的设备协议
    });

    /**
     * 错误监听
     * @see [onError](../README.md#onError)
     */
    this.bleApi.onError = (err) => {
      console.error('捕捉到错误', err.detail);
      this.updateBleOpStatus(BleOpStatusEnum.ERROR_OCCURED);
      wx.showToast({ title: `发生了错误`, icon: 'none' });
    };

    /**
     * 初始化回调
     * @see [onReady](../README.md#onReady)
     */
    this.bleApi.onReady = ({
      bleEnableState, //表示当前蓝牙是否为开启状态
    }) => {
      if (bleEnableState) {
        /**
         * 开始扫描
         * @see [startBleDeviceDiscovery](../README.md#startBleDeviceDiscovery)
         */
        this.updateBleOpStatus(BleOpStatusEnum.BLE_READY);
        this.bleApi.startBleDeviceDiscovery();
      } else {
        console.log('蓝牙状态为关闭');
        this.updateBleOpStatus(BleOpStatusEnum.BLE_DISABLED);
        this.setData({
          connecting: false,
          deviceId: '',
          deviceInfo: {},
          userIndex: '',
        });
      }
    };

    /**
     * 设置蓝牙监听事件
     * @see [setBleEventListener](../README.md#setBleEventListener)
     */
    this.bleApi.setBleEventListener({
      /**
       * 监听扫描到设备的回调
       * @see [onBleDeviceFound](../README.md#onBleDeviceFound)
       */
      onBleDeviceFound: (device) => {
        this.updateBleOpStatus(BleOpStatusEnum.DEVICE_FOUNDED);
        this.handleConnect(device);
      },
      /**
       * 监听蓝牙断开连接的回调
       * @see [onDisconnected](../README.md#onDisconnected)
       */
      onDisconnected: (device) => {
        console.log('设备连接已断开', device);
        this.updateBleOpStatus(BleOpStatusEnum.DISCONNECTED);
        this.setData({
          connecting: false,
          deviceId: '',
          deviceInfo: {},
          userIndex: '',
        });
      },
      /**
       * 监听蓝牙状态发生变化回调，连接成功或断开连接都会触发
       * @see [onBluetoothEnableChange](../README.md#onBluetoothEnableChange)
       */
      onBluetoothEnableChange: ({ available }) => {
        if (available) {
          this.updateBleOpStatus(BleOpStatusEnum.BLE_READY);
          this.bleApi.startBleDeviceDiscovery();
        } else {
          this.updateBleOpStatus(BleOpStatusEnum.BLE_DISABLED);
        }
        this.setData({ available });
      },
      /**
       * 监听设备连接成功回调
       * @see [onConnected](../README.md#onConnected)
       */
      onConnected: (device) => {
        console.log('设备已连接', device, device.deviceId);
        this.updateBleOpStatus(BleOpStatusEnum.CONNECTED);
        this.setData({ connecting: false, deviceId: device.deviceId });
      },
      /**
       * 监听停止扫描的回调
       * @see [onStopDiscoveryDevice](../README.md#onStopDiscoveryDevice)
       */
      onStopDiscoveryDevice: () => {
        console.log('已停止扫描');
        if (this.data.bleOpStatus !== BleOpStatusEnum.CONNECTING) {
          this.updateBleOpStatus(BleOpStatusEnum.STOP_SCANNING);
        }
      },
      /**
       * 监听开始扫描设备的回调
       * @see [onStartDiscoveryDevice](../README.md#onStartDiscoveryDevice)
       */
      onStartDiscoveryDevice: () => {
        console.log('开始扫描');
        this.updateBleOpStatus(BleOpStatusEnum.SCANNING);
      },
      /**
       * 连接超时
       */
      onConnectOverTime: () => {
        this.updateBleOpStatus(BleOpStatusEnum.CONNECT_OVERTIME);
        this.setData({ connecting: false });
      },
    });

    /**
     * 初始化
     * @see [init](../README.md#init)
     */
    this.bleApi.init();
  },

  onUnload: function() {
    if (this.bleApi) {
      this.bleApi.stop();
    }
  },

  /**
   * 链接设备
   * @param {*} device
   */
  async handleConnect(device) {
    const { connecting } = this.data;
    if (connecting) {
      console.log('当前正在连接，不再处理');
      return;
    }
    this.setData({ connecting: true });
    this.updateBleOpStatus(BleOpStatusEnum.CONNECTING);

    await this.bleApi.createBleConnection(device, {
      /**
       * 获取设备信息
       */
      onGetDeviceInfo: (device) => {
        console.log('获取设备信息', device);
        this.setData({ deviceInfo: device.info });
      },
      /**
       * 获取测量结果
       * @param {} data
       */
      onGetHandHeightData: (data) => {
        console.log('获取测量身高结果', data);
        const { height, heightUnit } = data;
        this.setData({ height, heightUnit });
      },
      /**
       * 同步时间结果
       */
      onSyncTimeResult: (state) => {
        console.log('同步时间结果', state);
      },
      /**
       * 设置当前用户结果
       */
      onSetUerResult: ({ setIndexState, setUnitState, userIndex }) => {
        if (!setUnitState) {
          wx.showToast({ title: '设置单位失败，请确认设备是否支持该单位', icon: 'none' });
        }

        if (!setIndexState) {
          wx.showToast({ title: '设置用户位失败', icon: 'none' });
        }

        if (setIndexState) this.setData({ userIndex });
      },
      /**
       * 获取存储数据
       * @param {*} historyData
       */
      onGetStoredDatas: (historyData) => {
        console.warn('获取存储数据', historyData);
        this.setData({ historyData });
      },
    });
  },

  /**
   * 重新连接设备
   */
  restart() {
    this.bleApi
      .stop()
      .then(() => {
        this.setData({ connected: false });
        this.bleApi.startBleDeviceDiscovery();
      })
      .catch((err) => {
        console.log('停止扫描失败', err);
      });
  },

  /**
   * 设置单位
   * @param unit 设备单位：01 -> cm ｜ 02 -> ft:in ｜ 04 -> in ｜ 08 ->ft | FF -> 不切换（默认）
   */
  async doSetUnit(e) {
    const unit = e.detail.value;

    console.warn('设置单位', unit);

    if (this.data.deviceId) {
      this.bleApi.callProtocolMethodAsync(this.data.deviceId, 'doSetUnit', [Number(unit)]);
    }
  },

  /**
   * 切换用户位
   * 1 | 2 | 3 | 0xff(不设置)
   * @param {} e
   */
  async doSetUserIndex(e) {
    const index = e.detail.value;

    console.warn('切换用户位', index);

    if (this.data.deviceId) {
      // TODO
      this.setData({ userIndex: index });
      this.bleApi.callProtocolMethodAsync(this.data.deviceId, 'doSetUserIndex', [Number(index)]);
    }
  },

  /**
   * 同步历史数据
   */
  async doSyncHistoryData() {
    const { deviceId } = this.data;

    console.warn('同步历史数据', deviceId);

    if (deviceId) {
      // 1 , 2 , 3 表示用户位
      this.bleApi.callProtocolMethodAsync(this.data.deviceId, 'doSyncHistoryData', [[1, 2, 3]]);
    }
  },

  updateBleOpStatus(status) {
    let text = '';
    switch (status) {
      case BleOpStatusEnum.NOOP:
        text = '空闲';
        break;
      case BleOpStatusEnum.BLE_DISABLED:
        text = '蓝牙不可用';
        break;
      case BleOpStatusEnum.BLE_READY:
        text = '请将手机靠近设备进行连接';
        break;
      case BleOpStatusEnum.SCANNING:
        text = '正在扫描设备';
        break;
      case BleOpStatusEnum.DEVICE_FOUNDED:
        text = '已发现设备';
        break;
      case BleOpStatusEnum.CONNECTING:
        text = '正在连接...';
        break;
      case BleOpStatusEnum.STOP_SCANNING:
        text = '停止扫描';
        break;
      case BleOpStatusEnum.CONNECTED:
        text = '已连接';
        break;
      case BleOpStatusEnum.CONNECT_FAILED:
        text = '连接设备失败';
        break;
      case BleOpStatusEnum.DISCONNECTED:
        text = '断开连接';
        break;
      case BleOpStatusEnum.CONNECT_OVERTIME:
        text = '连接超时';
        break;
      case BleOpStatusEnum.OPERATING:
        text = '正在测量';
        break;
      case BleOpStatusEnum.OPERATE_FINISHED:
        text = '重量已稳定';
        break;
      case BleOpStatusEnum.ERROR_OCCURED:
        text = '发生了错误';
        break;
      default:
        break;
    }

    this.setData({
      bleOpStatus: status,
      bleOpStatusText: text,
    });
  },
});
